<!DOCTYPE html>
<html lang="en">
<head>
  <meta charset="UTF-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge">
  <meta name="viewport" content="width=device-width, initial-scale=1.0">
  <title>手写promise</title>
</head>
<body>
  
</body>

<script>
const PENDING = 'pending'
const REJECTED = 'rejected'
const FULFILLED = 'fulfilled'

class MyPromise {
  // 构造函数立即执行
  constructor(excutor) {
    excutor(this.resolve, this.reject)
  }
  // 存储状态
  status = PENDING
  // 成功后的值
  value = null
  // 失败之后的原因
  reason = null

  // 存储成功回调函数
  onFulfilledCallback = []
  // 存储失败回调函数
  onRejectedCallback = []

  // 定义成功和失败方法
  resolve = (value) => {
    if (this.status === PENDING) {
      this.status = FULFILLED
      this.value = value
      // 对成功的回调进行循环调用
      while(this.onFulfilledCallback.length) {
        this.onFulfilledCallback.shift()(this.value)
      }
    }
  }
  reject = (reason) => {
    if (this.status === PENDING) {
      this.status = REJECTED
      this.reason = reason
      // 对失败的回调进行循环调用
      if(this.onRejectedCallback.length) {
        this.onRejectedCallback.shift()(this.reason)
      }
    }
  }
  then = (onFulfilled, onRejected)=> {
    // 如果状态为成功
    if (this.status === FULFILLED) {
      onFulfilled(this.value)
    } else if(this.status === REJECTED) {
      // 如果状态为失败
      onRejected(this.reason)
    } else if(this.status === PENDING) {
      // 不知道是哪种状态，此时把成功和失败的回调函数存储起来，供后面调用
      this.onFulfilledCallback.push(onFulfilled)
      this.onRejectedCallback.push(onRejected)
    }
    return this
  }
}

/**
 * 实现同步和异步的调用
 * 实现then的链式调用 , 避免多次调用被覆盖
 */
let promise = new MyPromise((resolve, reject) => {
  console.log(00)
  // 异步执行，等待执行reject修改status状态，然后在执行then里面的方法
  setTimeout(() => {
    resolve('ok')
  }, 3000)
})
promise.then(data => {
  console.log(1, data)
}, err => {
  console.log(2, err)
}).then(data => {
  console.log('3', data)
})
</script>


</html>